<template>
  <div class="time-slot-container">
    <div class="time-grid">
      <div 
        v-for="(hour, hIndex) in 24" 
        :key="hIndex" 
        class="hour-block"
      >
        <div class="hour-label">{{ hour }}:00</div>
        <div class="minute-grid">
          <div 
            v-for="(minute, mIndex) in 12" 
            :key="`${hIndex}-${mIndex}`"
            :class="{
              'time-slot': true,
              'selected': isSelected(hIndex, mIndex),
              'selecting': isSelecting && isWithinSelection(hIndex, mIndex)
            }"
            @mousedown="startSelection(hIndex, mIndex)"
            @mouseenter="continueSelection(hIndex, mIndex)"
          ></div>
        </div>
      </div>
    </div>
    <div class="selection-info" v-if="selectedSlots.length > 0">
      已选择: {{ formatSelectedTime() }}
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'

// 存储选中的时间块 [hour, minute]
const selectedSlots = ref([])
// 选择状态相关
const isSelecting = ref(false)
const startSlot = ref(null)
const endSlot = ref(null)

// 计算选中的时间段文本
const formatSelectedTime = () => {
  if (selectedSlots.value.length === 0) return ''
  
  const sortedSlots = [...selectedSlots.value].sort((a, b) => {
    if (a[0] !== b[0]) return a[0] - b[0]
    return a[1] - b[1]
  })
  
  const startTime = formatTime(sortedSlots[0][0], sortedSlots[0][1])
  const endTime = formatTime(
    sortedSlots[sortedSlots.length - 1][0], 
    sortedSlots[sortedSlots.length - 1][1] + 1
  )
  
  return `${startTime} - ${endTime}`
}

// 格式化单个时间点
const formatTime = (hour, minuteIndex) => {
  const minute = minuteIndex * 5
  return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
}

// 判断时间块是否被选中
const isSelected = (hour, minuteIndex) => {
  return selectedSlots.value.some(
    slot => slot[0] === hour && slot[1] === minuteIndex
  )
}

// 判断时间块是否在当前选择范围内（鼠标拖动过程中）
const isWithinSelection = (hour, minuteIndex) => {
  if (!startSlot.value) return false
  
  const startH = startSlot.value[0]
  const startM = startSlot.value[1]
  const endH = endSlot.value ? endSlot.value[0] : hour
  const endM = endSlot.value ? endSlot.value[1] : minuteIndex
  
  // 确保开始和结束点正确排序
  const [minH, maxH] = startH <= endH ? [startH, endH] : [endH, startH]
  let minM = startM
  let maxM = endM
  
  if (startH === endH) {
    [minM, maxM] = startM <= endM ? [startM, endM] : [endM, startM]
  } else if (startH > endH) {
    [minM, maxM] = [endM, startM]
  }
  
  if (hour < minH || hour > maxH) return false
  if (hour === minH && minuteIndex < minM) return false
  if (hour === maxH && minuteIndex > maxM) return false
  
  return true
}

// 开始选择
const startSelection = (hour, minuteIndex) => {
  isSelecting.value = true
  startSlot.value = [hour, minuteIndex]
  endSlot.value = null
  
  // 清除现有选择（如果是新的选择操作）
  if (!event.ctrlKey && !event.metaKey) {
    selectedSlots.value = []
  }
}

// 继续选择（鼠标移动时）
const continueSelection = (hour, minuteIndex) => {
  if (!isSelecting.value) return
  endSlot.value = [hour, minuteIndex]
  
  // 更新选中的时间块
  updateSelectedSlots()
}

// 更新选中的时间块数组
const updateSelectedSlots = () => {
  if (!startSlot.value || !endSlot.value) return
  
  const startH = startSlot.value[0]
  const startM = startSlot.value[1]
  const endH = endSlot.value[0]
  const endM = endSlot.value[1]
  
  // 确保开始和结束点正确排序
  const [minH, maxH] = startH <= endH ? [startH, endH] : [endH, startH]
  let minM = startM
  let maxM = endM
  
  if (startH === endH) {
    [minM, maxM] = startM <= endM ? [startM, endM] : [endM, startM]
  } else if (startH > endH) {
    [minM, maxM] = [endM, startM]
  }
  
  // 生成选中的时间块数组
  const slots = []
  for (let h = minH; h <= maxH; h++) {
    let startMinute = h === minH ? minM : 0
    let endMinute = h === maxH ? maxM : 11
    
    for (let m = startMinute; m <= endMinute; m++) {
      slots.push([h, m])
    }
  }
  
  // 如果是添加选择（按住Ctrl/Command），则合并到现有选择
  if (event.ctrlKey || event.metaKey) {
    // 过滤掉重复的选择
    const uniqueSlots = [...new Set([
      ...selectedSlots.value.map(s => `${s[0]}-${s[1]}`),
      ...slots.map(s => `${s[0]}-${s[1]}`)
    ])].map(s => s.split('-').map(Number))
    
    selectedSlots.value = uniqueSlots
  } else {
    selectedSlots.value = slots
  }
}

// 监听鼠标释放事件，结束选择
onMounted(() => {
  const stopSelecting = () => {
    isSelecting.value = false
    startSlot.value = null
    endSlot.value = null
  }
  
  document.addEventListener('mouseup', stopSelecting)
  
  // 组件卸载时移除事件监听
  return () => {
    document.removeEventListener('mouseup', stopSelecting)
  }
})
</script>

<style scoped>
.time-slot-container {
  max-width: 800px;
  margin: 20px auto;
  font-family: Arial, sans-serif;
}

.time-grid {
  display: flex;
  flex-direction: column;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
}

.hour-block {
  display: flex;
  border-bottom: 1px solid #e0e0e0;
}

.hour-block:last-child {
  border-bottom: none;
}

.hour-label {
  width: 60px;
  padding: 5px;
  text-align: center;
  background-color: #f5f5f5;
  border-right: 1px solid #e0e0e0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}

.minute-grid {
  flex: 1;
  display: flex;
}

.time-slot {
  flex: 1;
  height: 20px;
  border-right: 1px solid #e0e0e0;
  cursor: pointer;
  transition: background-color 0.1s;
}

.time-slot:last-child {
  border-right: none;
}

.time-slot:hover {
  background-color: #e6f7ff;
}

.selected {
  background-color: #1890ff;
}

.selecting {
  background-color: #40a9ff;
}

.selection-info {
  margin-top: 10px;
  padding: 8px 12px;
  background-color: #fafafa;
  border-radius: 4px;
  border: 1px solid #e8e8e8;
  font-size: 14px;
}
</style>  